using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using viBook.Common;
using viBook.Helpers;
using viBook.Models;

namespace viBook.Repositories
{
    public class ChapterCommentRepository : IChapterCommentRepository
    {
        private readonly viBookContext _context = new viBookContext();

        public IQueryable<ChapterComment> All
        {
            get { return _context.ChapterComments; }
        }

        #region IChapterCommentRepository Members

        IEnumerable<ChapterComment> IChapterCommentRepository.FetchCommentsByPage(int chapterId, int pageNo,int userId)
        {
            IEnumerable<ChapterComment> comments =
                _context.ChapterComments.Where(cc=>cc.ChapterId==chapterId&& !cc.IsBlocked).OrderByDescending(c => c.CreatedDate).Skip(Constant.MaximunCommentPerChapter*
                                                                             (pageNo - 1)).Take(
                                                                                 Constant.MaximunCommentPerChapter).ToList();
            foreach (var chapterComment in comments)
            {
                chapterComment.IsLiked =
                    _context.ChapterCommentLikes.Any(ccl => ccl.CommentId == chapterComment.Id && ccl.UserId == userId);
                chapterComment.IsReported =
                    _context.ReportOnChapterComments.Any(
                        rocc => rocc.ChapterCommentId == chapterComment.Id && rocc.UserId == userId);
                chapterComment.IsAuthorized = (chapterComment.UserId == userId);
            }
            return comments;
        }

        public void InsertOrUpdate(ChapterComment chapterComment)
        {
            if (chapterComment.Id == default(int))
            {
                chapterComment.CreatedDate = DateTime.Now;
                _context.ChapterComments.Add(chapterComment);
            }
            else
            {
                _context.Entry(chapterComment).State = EntityState.Modified;
            }
            Save();
        }

        public void Delete(int id)
        {
            ChapterComment comment = _context.ChapterComments.Find(id);
            _context.ChapterComments.Remove(comment);
        }

        public void Save()
        {
            _context.SaveChanges();
        }

        public DataFeedback VoteUp(int id, int userId)
        {

            var feedback = new DataFeedback();
            var existLike = _context.ChapterCommentLikes.FirstOrDefault(ccl => ccl.UserId == userId && ccl.CommentId == id);
            if (existLike == null)
            {
                _context.ChapterCommentLikes.Add(new ChapterCommentLike
                {
                    CommentId = id,
                    UserId = userId,
                    CreatedDate = DateTime.Now
                });
                Save();
                var chapterComment = _context.ChapterComments.Find(id);
                chapterComment.Like++;
                InsertOrUpdate(chapterComment);
                Save();
                feedback.IsSuccess = true;
            }
            else
            {
                _context.ChapterCommentLikes.Remove(existLike);
                Save();
                var bookComment = _context.ChapterComments.Find(id);
                bookComment.Like--;
                InsertOrUpdate(bookComment);
                Save();
                feedback.IsSuccess = false;
            }
            return feedback;
        }

        public DataFeedback VoteDown(int id, int userId)
        {
             var feedback = new DataFeedback();
            var existLike = _context.ChapterCommentLikes.FirstOrDefault(ccl => ccl.UserId == userId && ccl.CommentId == id);
            if (existLike != null)
            {
                _context.ChapterCommentLikes.Remove(existLike);
                Save();
                var bookComment = _context.ChapterComments.Find(id);
                bookComment.Like--;
                InsertOrUpdate(bookComment);
                Save();
                feedback.IsSuccess = true;
            }
            return feedback;
        }

        public void Report(int id, int userId)
        {
            ReportOnChapterComment found =
                _context.ReportOnChapterComments.FirstOrDefault(c => c.ChapterCommentId == id && c.UserId == userId);
            if (found != null) return;
            var reportComment = new ReportOnChapterComment
                                    {
                                        ChapterCommentId = id,
                                        UserId = userId,
                                        ReportedDate = DateTime.Now
                                    };
            _context.ReportOnChapterComments.Add(reportComment);
            _context.SaveChanges();
        }

        public ChapterComment Find(int id)
        {
            return _context.ChapterComments.Find(id);
        }
        #endregion

    }

    public interface IChapterCommentRepository
    {
        IEnumerable<ChapterComment> FetchCommentsByPage(int chapterId, int pageNo,int userId);
        void InsertOrUpdate(ChapterComment chapterComment);
        void Delete(int id);
        void Save();
        DataFeedback VoteUp(int id, int userId);
        DataFeedback VoteDown(int id, int userId);
        void Report(int id, int userId);
        ChapterComment Find(int id);
    }
}
